﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows;

namespace Helloworld.FontsBitmap
{
    class BitmapFont
    {
        public Texture2D Image;
        public Font[] ArrayFont;
        public int LineHeight;
        public int LineBase;
        public int xpos;
        public float scale;
        public BitmapFont(Texture2D image, String FilePath)
        {
            this.Image = image;
            getArrayFont(FilePath);
            scale = 1f;
        }

       

        public String getStringFromFile(String fileName)
        {
            var resource = App.GetResourceStream(new Uri(fileName, UriKind.Relative));
            StreamReader reader = new StreamReader(resource.Stream, Encoding.UTF8);
            return reader.ReadToEnd();
           
        }

        public void getArrayFont(String filePath)
        {
            String info=getStringFromFile(filePath);
            String[] arrayString = info.Split('\n');
            String beginTotal = "chars count=";
            String lineheightStringbegin = "lineHeight=";
            String lineheightStringend = " base=";
            String linebaseStringend = " scaleW=";
            int indexbeginLineheight=info.IndexOf(lineheightStringbegin);
            int indexendLineheight=info.IndexOf(lineheightStringend);
            LineHeight = int.Parse(info.Substring(indexbeginLineheight+lineheightStringbegin.Length,indexendLineheight-indexbeginLineheight-lineheightStringbegin.Length));

            indexbeginLineheight = info.IndexOf(lineheightStringend);
            indexendLineheight = info.IndexOf(linebaseStringend);
            LineBase = int.Parse(info.Substring(indexbeginLineheight + lineheightStringend.Length, indexendLineheight - indexbeginLineheight - lineheightStringend.Length));

            int index = 0;
            for (int i = 0; i < arrayString.Length; i++)
            {

                if (arrayString[i].StartsWith(beginTotal))
                {
                    int n = int.Parse(arrayString[i].Substring(beginTotal.Length));
                    ArrayFont = new Font[n];
                }
                if (arrayString[i].StartsWith("char id="))
                {
                    ArrayFont[index]= fillFontString(arrayString[i]);


                    index ++;
                }
            }
            
        }

        public Font fillFontString(String s)
        {
           //char id=33 x=184 y=145 width=6 height=14 xoffset=0 yoffset=15 xadvance=5 page=0 chnl=0 letter="!"|97
            String id=getStringBetween(s, "char id=", " x=");
            String x=getStringBetween(s, " x=", " y=");
            String y=getStringBetween(s, " y=", " width=");
            String w=getStringBetween(s, " width=", " height=");
            String h=getStringBetween(s, " height=", " xoffset=");
            String xoff = getStringBetween(s, " xoffset=", " yoffset=");
            String yoff = getStringBetween(s, " yoffset=", " xadvance=");
            String letter = getStringBetween(s, " letter=", "12letter");
            int width=int.Parse(w);
            if (width == 0) width = LineBase;
            return new Font(int.Parse(id), int.Parse(x), int.Parse(y), int.Parse(xoff), int.Parse(yoff), width, int.Parse(h), letter[1]);
        }

        public String getStringBetween(String root, String begin, String end)
        {
            int startIndex = root.IndexOf(begin);
            int endIndex = root.IndexOf(end);
            if (endIndex < startIndex) return root.Substring(startIndex + begin.Length);
                return root.Substring(startIndex + begin.Length, endIndex-startIndex-begin.Length);
            
        }

        public Font getFont(char c)
        {
            for (int i = 0; i < ArrayFont.Length; i++)
            {
                if (ArrayFont[i].charset == c) return ArrayFont[i];
            }
            return null;
        }

        public void draw(SpriteBatch batch, String s, int x, int y)
        {
            xpos=x;
            for(int i=0;i<s.Length;i++){
                Font f=getFont(s[i]);
                if(f!=null){
                    batch.Draw(Image, new Rectangle((int)(xpos+f.xoffset*scale), (int)(y+f.yoffset*scale), (int)(f.Width*scale),(int) (f.Height*scale)), new Rectangle(f.xPos, f.yPos, f.Width, f.Height), Color.White);
                    xpos += (int)(scale*f.Width);
                        
                }
            }
        }

        public int getLength(String s)
        {
            int length = 0;
            for (int i = 0; i < s.Length; i++)
            {
                Font f = getFont(s[i]);
                if (f != null)
                {
                    length += f.Width;
                }
            }
            return (int)(length*scale);
        }

        public void drawMutiLineLeft(SpriteBatch batch, String s, int x, int y, int LineWidth)
        {
            String[] lineString = s.Split('\n');
            int maxX = x + LineWidth;
            xpos = x;
            int ypos=y; 
            for (int i = 0; i < lineString.Length; i++)
            {
                String[] word = lineString[i].Split(' ');
                for (int j = 0; j < word.Length; j++)
                {
                    if (xpos + getLength(word[j]) > maxX && xpos!=x)
                    {
                        xpos = x;
                        ypos += (int)(LineHeight*scale);
                    }
                    draw(batch, word[j]+" ", xpos, ypos);
                    
                }
                ypos += (int)(LineHeight*scale);
            }
        }

        public void drawMutiLineCenter(SpriteBatch batch, String s, int x, int y, int LineWidth)
        {
            String[] lineString = s.Split('\n');
            xpos = x;
            int ypos = y;
            for (int i = 0; i < lineString.Length; i++)
            {
                String[] word = lineString[i].Split(' ');
                int index = 0;
                String wordLine="";
                do
                {
                    wordLine += word[index];
                    index++;
                    if (index >=word.Length || getLength(wordLine + word[index]) > LineWidth)
                    {
                        int w = getLength(wordLine);
                        xpos = x + (LineWidth - w) / 2;
                        draw(batch, wordLine, xpos, ypos);
                        ypos += (int)(LineHeight * scale);
                        wordLine = "";
                    }
                    wordLine += " ";
                } while (index < word.Length);
                     ypos += (int)(LineHeight*scale);
            }
        }
        public void drawMutiLineRight(SpriteBatch batch, String s, int x, int y, int LineWidth)
        {
            String[] lineString = s.Split('\n');
            xpos = x;
            int ypos = y;
            for (int i = 0; i < lineString.Length; i++)
            {
                String[] word = lineString[i].Split(' ');
                int index = 0;
                String wordLine="";
                do
                {
                    wordLine += word[index];
                    index++;
                    if (index >=word.Length || getLength(wordLine + word[index]) > LineWidth)
                    {
                        int w = getLength(wordLine);
                        xpos = x + (LineWidth - w);
                        draw(batch, wordLine, xpos, ypos);
                        ypos += (int)(LineHeight * scale);
                        wordLine = "";
                    }
                    wordLine += " ";
                } while (index < word.Length);
                     ypos += (int)(LineHeight*scale);
            }
        }
    }
    
    

}

